home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s3.arc / PIBHOSTC.MOD < prev    next >
Text File  |  1987-09-09  |  49KB  |  1,275 lines

  1. (*----------------------------------------------------------------------*)
  2. (*      Reset_The_Port --- Reset serial port to issue modem commands    *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Reset_The_Port;
  6.  
  7. BEGIN (* Reset_The_Port *)
  8.  
  9.    IF ( Baud_Rate <> 300 ) THEN
  10.       New_Baud := 300
  11.    ELSE
  12.       New_Baud := 150;
  13.  
  14.    Async_Reset_Port( Comm_Port, New_Baud, Parity, Data_Bits, Stop_Bits );
  15.  
  16.    Set_Status_Line_Name( Short_Terminal_Name );
  17.    Write_To_Status_Line( Status_Line_Name, 1 );
  18.  
  19.    Host_Status( Cur_Host_Status );
  20.  
  21. END   (* Reset_The_Port *);
  22.  
  23. (*----------------------------------------------------------------------*)
  24. (*      Jump_To_Dos --- allow privileged users to access DOS directly   *)
  25. (*----------------------------------------------------------------------*)
  26.  
  27. PROCEDURE Jump_To_Dos;
  28.  
  29. (*----------------------------------------------------------------------*)
  30. (*                                                                      *)
  31. (*     Procedure:  Jump_To_Dos                                          *)
  32. (*                                                                      *)
  33. (*     Purpose:    Allows use of DOS remotely.                          *)
  34. (*                                                                      *)
  35. (*     Calling Sequence:                                                *)
  36. (*                                                                      *)
  37. (*        Jump_To_Dos;                                                  *)
  38. (*                                                                      *)
  39. (*     Remarks:                                                         *)
  40. (*                                                                      *)
  41. (*         A batch file is constructed which executes the CTTY command. *)
  42. (*         This batch file is executed using the Dos EXEC function.     *)
  43. (*         When the remote user types EXIT, control is returned here.   *)
  44. (*         Note:  A user must have a privilege level of "S" (Special)   *)
  45. (*                to use this function.                                 *)
  46. (*                                                                      *)
  47. (*----------------------------------------------------------------------*)
  48.  
  49. VAR
  50.    Batch_File : Text_File;
  51.    Save_Close : BOOLEAN;
  52.    I          : INTEGER;
  53.    CTTY_Device: STRING[8];
  54.  
  55. BEGIN (* Jump_To_Dos *)
  56.  
  57.    Host_Status('Jump to DOS');
  58.  
  59.    Write_Log( 'Jump to DOS.' , FALSE, FALSE );
  60.  
  61.                                    (* Open batch file *)
  62.  
  63.    ASSIGN( Batch_File , 'PIBTCTTY.BAT' );
  64.       (*$I-*)
  65.    REWRITE( Batch_File );
  66.       (*$I+*)
  67.  
  68.    IF ( Int24Result <> 0 ) THEN
  69.       BEGIN
  70.          Host_Send_String_With_CR('Can''t jump to DOS.');
  71.          Host_Section := Last_Host_Sect;
  72.          EXIT;
  73.       END;
  74.                                    (* Construct MODE and CTTY statements *)
  75.  
  76.    IF ( LENGTH( Host_CTTY_Device ) > 0 ) THEN
  77.       CTTY_Device := Host_CTTY_Device
  78.    ELSE
  79.       CTTY_Device := 'COM';
  80.  
  81.    WRITELN( Batch_File , 'ECHO OFF');
  82.    WRITELN( Batch_File , 'MODE COM', Comm_Port,':',Baud_Rate,',',
  83.                          Parity,',',Data_Bits,',',Stop_Bits );
  84.    WRITELN( Batch_File , 'CTTY ', CTTY_Device, Comm_Port );
  85.    WRITELN( Batch_File , 'COMMAND' );
  86.  
  87.       (*$I-*)
  88.    CLOSE( Batch_File );
  89.       (*$I+*)
  90.  
  91.    IF ( Int24Result <> 0 ) THEN
  92.       BEGIN
  93.          Host_Send_String_With_CR('Can''t jump to DOS.');
  94.          Host_Section := Last_Host_Sect;
  95.          EXIT;
  96.       END;
  97.                                    (* Make sure async interrupts closed down *)
  98.  
  99.    Save_Close         := Close_Comm_For_Dos;
  100.    Close_Comm_For_Dos := TRUE;
  101.                                    (* Reset modem in case of line drop *)
  102.  
  103.    IF ( NOT ( Hard_Wired OR Local_Host ) ) THEN
  104.       BEGIN
  105.  
  106.          Host_Send_String_With_CR(' ');
  107.          Host_Send_String_With_CR('Resetting modem.  Ignore any garbage that appears.');
  108.          Host_Send_String_With_CR(' ');
  109.  
  110.                                    (* Wait for remote to get message *)
  111.  
  112.          Async_Drain_Output_Buffer( Five_Seconds );
  113.  
  114.                                    (* Reset comm parameters so that *)
  115.                                    (* modem commands don't go to    *)
  116.                                    (* remote.                       *)
  117.          Reset_The_Port;
  118.                                    (* Restore startup mode on modem *)
  119.  
  120.          Send_Modem_Command( Modem_Host_UnSet );
  121.  
  122.                                    (* Wait for remote to get message *)
  123.  
  124.          Async_Drain_Output_Buffer( Five_Seconds );
  125.  
  126.                                    (* Reset port *)
  127.  
  128.          Async_Reset_Port( Comm_Port, Baud_Rate, Parity, Data_Bits, Stop_Bits );
  129.  
  130.          Set_Status_Line_Name( Short_Terminal_Name );
  131.          Write_To_Status_Line( Status_Line_Name, 1 );
  132.  
  133.       END;
  134.                                    (* Send message message indicating *)
  135.                                    (* attempt to jump to DOS          *)
  136.  
  137.    Host_Send_String_With_CR(' ');
  138.    Host_Send_String_With_CR('Jumping to DOS.');
  139.    Host_Send_String_With_Cr('Type EXIT to return to PibTerm.');
  140.    Host_Send_String_With_CR(' ');
  141.                                    (* Wait for remote to get message *)
  142.  
  143.    Async_Drain_Output_Buffer( Five_Seconds );
  144.  
  145.                                    (* Execute batch file *)
  146.    DosJump( 'PIBTCTTY' );
  147.                                    (* Erase batch file *)
  148.       (*$I-*)
  149.    ERASE( Batch_File );
  150.       (*$I+*)
  151.  
  152.    I := Int24Result;
  153.                                    (* Reinitialize modem for host mode *)
  154.  
  155.    IF ( NOT ( Hard_Wired OR Local_Host ) ) THEN
  156.       BEGIN
  157.          Reset_The_Port;
  158.          Send_Modem_Command( Modem_Host_Set );
  159.          Async_Drain_Output_Buffer( Five_Seconds );
  160.          Async_Reset_Port( Comm_Port, Baud_Rate, Parity, Data_Bits, Stop_Bits );
  161.          Set_Status_Line_Name( Short_Terminal_Name );
  162.          Write_To_Status_Line( Status_Line_Name, 1 );
  163.          DELAY( Two_Second_Delay );
  164.       END;
  165.                                    (* Restore previous close_comm flag *)
  166.  
  167.    Close_Comm_For_Dos := Save_Close;
  168.  
  169.                                    (* Return to last section used *)
  170.    Host_Section := Last_Host_Sect;
  171.  
  172.    Host_Status(Cur_Host_Status);
  173.  
  174. END   (* Jump_To_Dos *);
  175.  
  176. (*----------------------------------------------------------------------*)
  177. (*         Process_Host_Commands --- Process main menu commands         *)
  178. (*----------------------------------------------------------------------*)
  179.  
  180. PROCEDURE Process_Host_Commands( VAR Done: BOOLEAN );
  181.  
  182. (*----------------------------------------------------------------------*)
  183. (*                                                                      *)
  184. (*     Procedure:  Process_Host_Commands                                *)
  185. (*                                                                      *)
  186. (*     Purpose:    Controls processing of main menu commands.           *)
  187. (*                                                                      *)
  188. (*     Calling Sequence:                                                *)
  189. (*                                                                      *)
  190. (*        Process_Host_Commands( VAR Done: BOOLEAN );                   *)
  191. (*                                                                      *)
  192. (*           Done --- set TRUE if quit command entered or carrier       *)
  193. (*                    dropped.                                          *)
  194. (*                                                                      *)
  195. (*----------------------------------------------------------------------*)
  196.  
  197. VAR
  198.    Back        : BOOLEAN;
  199.    Ch          : CHAR;
  200.    Sysop_Found : BOOLEAN;
  201.    Found_Ch    : BOOLEAN;
  202.  
  203. LABEL
  204.    ReadChar;
  205.  
  206. (*----------------------------------------------------------------------*)
  207. (*   Display_Host_Commands --- Display command list for remote user     *)
  208. (*----------------------------------------------------------------------*)
  209.  
  210. PROCEDURE Display_Host_Commands;
  211.  
  212. (*----------------------------------------------------------------------*)
  213. (*                                                                      *)
  214. (*     Procedure: Display_Host_Commands                                 *)
  215. (*                                                                      *)
  216. (*     Purpose:   Displays menu of PibTerm host commands and prompts    *)
  217. (*                for command entry.                                    *)
  218. (*                                                                      *)
  219. (*     Calling sequence:                                                *)
  220. (*                                                                      *)
  221. (*        Display_Host_Commands;                                        *)
  222. (*                                                                      *)
  223. (*----------------------------------------------------------------------*)
  224.  
  225. BEGIN (* Display_Host_Commands *)
  226.  
  227.    IF ( NOT Expert_On ) THEN
  228.       BEGIN
  229.          Host_Send_String_With_CR(' ');
  230.          Host_Send_String_With_CR('======================================================');
  231.          Host_Send_String_With_CR('=             PibTerm Host Mode Main Menu            =');
  232.          Host_Send_String_With_CR('======================================================');
  233.          Host_Send_String_With_CR(' ');
  234.          Host_Send_String_With_CR('     E=Enter message');
  235.          Host_Send_String_With_CR('     R=Read message');
  236.          Host_Send_String_With_CR('     S=Scan messages');
  237.          Host_Send_String_With_CR('     P=Personal message scan');
  238.          Host_Send_String_With_CR('     Q=Quit and logoff');
  239.          Host_Send_String_With_CR('     F=File transfers');
  240.          Host_Send_String_With_CR('     G=Gossip mode');
  241.          Host_Send_String_With_CR('     X=Expert mode');
  242.          Host_Send_String_With_CR('     C=Send comments');
  243.          Host_Send_String_With_CR('     W=Read welcome message');
  244.          IF ( Privilege = 'S' ) THEN
  245.             Host_Send_String_With_CR('     J=Jump to DOS');
  246.          Host_Send_String_With_CR(' ');
  247.          Host_Send_String_With_CR('======================================================');
  248.          Host_Send_String_And_Echo('Enter command ? ');
  249.       END
  250.    ELSE
  251.       BEGIN
  252.          Host_Send_String_With_CR(' ');
  253.          IF ( Privilege = 'S' ) THEN
  254.             Host_Send_String_And_Echo('Main (E,R,S,P,Q,F,G,X,C,W,J) ? ')
  255.          ELSE
  256.             Host_Send_String_And_Echo('Main (E,R,S,P,Q,F,G,X,C,W) ? ');
  257.       END;
  258.  
  259.    IF ( NOT Local_Host ) THEN
  260.       Async_Purge_Buffer;
  261.  
  262. END   (* Display_Host_Commands *);
  263.  
  264. (*----------------------------------------------------------------------*)
  265. (*            Page_Sysop --- Page sysop to enter gossip mode            *)
  266. (*----------------------------------------------------------------------*)
  267.  
  268. PROCEDURE Page_Sysop( VAR Sysop_Found : BOOLEAN );
  269.  
  270. (*----------------------------------------------------------------------*)
  271. (*                                                                      *)
  272. (*     Procedure:  Page_Sysop                                           *)
  273. (*                                                                      *)
  274. (*     Purpose:    Pages Sysop to enter gossip mode.                    *)
  275. (*                                                                      *)
  276. (*     Calling Sequence:                                                *)
  277. (*                                                                      *)
  278. (*        Page_Sysop( VAR Sysop_Found : BOOLEAN );                      *)
  279. (*                                                                      *)
  280. (*           Sysop_Found --- TRUE if sysop responds.                    *)
  281. (*                                                                      *)
  282. (*     Remarks:                                                         *)
  283. (*                                                                      *)
  284. (*        If silent mode is on (Alt_M) then this page is not performed. *)
  285. (*                                                                      *)
  286. (*----------------------------------------------------------------------*)
  287.  
  288. VAR
  289.    Timer: REAL;
  290.    I    : INTEGER;
  291.    Ch   : CHAR;
  292.  
  293. BEGIN (* Page_Sysop *)
  294.  
  295.    Write_Log('Page SYSOP.', FALSE, FALSE );
  296.  
  297.    Host_Status('Paging SYSOP');
  298.  
  299.    Host_Send_String_With_CR(' ');
  300.  
  301.    Sysop_Found := FALSE;
  302.  
  303.    IF ( NOT Silent_Mode ) THEN
  304.       BEGIN
  305.  
  306.          Host_Send_String_With_CR('Summoning Sysop (^X cancels) ...');
  307.  
  308.          Timer := 30;
  309.  
  310.          REPEAT
  311.  
  312.             FOR I := 1 TO 5 DO
  313.                WRITE( CHR( BELL ) );
  314.  
  315.             IF Async_Receive( Ch ) THEN
  316.                IF ( Ch = ^X ) THEN
  317.                   Timer := 0.0;
  318.  
  319.             IF KeyPressed THEN
  320.                BEGIN
  321.                   READ( Kbd, Ch );
  322.                   IF ( Ch = CHR( ESC ) ) AND KeyPressed THEN
  323.                      READ( Kbd , Ch );
  324.                   IF ( Ch <> ^X ) THEN
  325.                      Sysop_Found := TRUE
  326.                   ELSE
  327.                      Timer := 0.0;
  328.                END;
  329.  
  330.             DELAY( One_Second_Delay );
  331.  
  332.             Timer := Timer - 1.0;
  333.  
  334.          UNTIL ( Timer <= 0.0 ) OR ( Sysop_Found );
  335.  
  336.       END
  337.    ELSE
  338.       Host_Send_String_With_CR('Sysop not available, gossip cancelled.');
  339.  
  340.    Host_Status(Cur_Host_Status);
  341.  
  342. END   (* Page_Sysop *);
  343.  
  344. (*----------------------------------------------------------------------*)
  345. (*           Get_A_Message  --- Get text of message from user           *)
  346. (*----------------------------------------------------------------------*)
  347.  
  348. PROCEDURE Get_A_Message( VAR F: Text_File );
  349.  
  350. (*----------------------------------------------------------------------*)
  351. (*                                                                      *)
  352. (*     Procedure:  Get_A_Message                                        *)
  353. (*                                                                      *)
  354. (*     Purpose:    Prompts for line by line message entry.              *)
  355. (*                                                                      *)
  356. (*     Calling Sequence:                                                *)
  357. (*                                                                      *)
  358. (*        Get_A_Message( VAR F: Text_File );                            *)
  359. (*                                                                      *)
  360. (*           F --- file to write message to.                            *)
  361. (*                                                                      *)
  362. (*     Remarks:                                                         *)
  363. (*                                                                      *)
  364. (*        This routine handles text entry for both regular messages and *)
  365. (*        comments.                                                     *)
  366. (*                                                                      *)
  367. (*----------------------------------------------------------------------*)
  368.  
  369. BEGIN (* Get_A_Message *)
  370.  
  371.    WITH User_List^[Cur_User] DO
  372.       WRITELN( F, '== From:    ', Fname, ' ', Lname );
  373.    WRITELN( F, '== To:      ',Recipient_Name );
  374.    WRITELN( F, '== Date:    ',DateString );
  375.    WRITELN( F, '== Time:    ',TimeString( TimeOfDay , Military_Time ) );
  376.    WRITELN( F, '== Subject: ',Message_Subject );
  377.  
  378.    Host_Send_String( CR_LF_Host );
  379.    Host_Send_String_With_CR('Enter message.   Empty line terminates.');
  380.  
  381.    REPEAT
  382.       Host_Send_String( CR_LF_Host );
  383.       Host_Prompt_And_Read_String('> ', Message_Line, TRUE );
  384.       IF LENGTH( Message_Line ) > 0 THEN
  385.          WRITELN( F, ' ', Message_Line );
  386.    UNTIL ( LENGTH( Message_Line ) = 0 );
  387.  
  388.    WRITELN( F, '== End');
  389.  
  390.    Host_Send_String( CR_LF_Host );
  391.    Host_Send_String_With_CR('Message entered.');
  392.  
  393. END   (* Get_A_Message *);
  394.  
  395. (*----------------------------------------------------------------------*)
  396. (*           Enter_Message  --- Enter a message into message base       *)
  397. (*----------------------------------------------------------------------*)
  398.  
  399. PROCEDURE Enter_Message;
  400.  
  401. (*----------------------------------------------------------------------*)
  402. (*                                                                      *)
  403. (*     Procedure:  Enter_Message                                        *)
  404. (*                                                                      *)
  405. (*     Purpose:    Enters message into message base.                    *)
  406. (*                                                                      *)
  407. (*     Calling Sequence:                                                *)
  408. (*                                                                      *)
  409. (*        Enter_Message;                                                *)
  410. (*                                                                      *)
  411. (*     Calls:                                                           *)
  412. (*                                                                      *)
  413. (*        Open_For_Append                                               *)
  414. (*        Get_A_Message                                                 *)
  415. (*                                                                      *)
  416. (*----------------------------------------------------------------------*)
  417.  
  418. VAR
  419.    Quit: BOOLEAN;
  420.    Ierr: INTEGER;
  421.  
  422. BEGIN (* Enter_Message *)
  423.  
  424.    Host_Status('Enter message');
  425.  
  426.    Quit := FALSE;
  427.                                    (* Open message file *)
  428.  
  429.    ASSIGN( Message_File, Home_Dir + 'PIBTERM.MSG' );
  430.       (*$I-*)
  431.    RESET ( Message_File );
  432.       (*$I+*)
  433.                                    (* If it exists, open for append.       *)
  434.                                    (* If it doesn't exist, open for write. *)
  435.    IF Int24Result <> 0 THEN
  436.       BEGIN
  437.          WRITELN('Creating message file PIBTERM.MSG');
  438.             (*$I-*)
  439.          REWRITE( Message_File );
  440.             (*$I+*)
  441.          IF Int24Result <> 0 THEN
  442.             BEGIN
  443.                Host_Send_String_With_CR('Sorry, no more room for messages');
  444.                Quit := TRUE;
  445.             END;
  446.       END
  447.    ELSE
  448.       BEGIN
  449.  
  450.             (*$I-*)
  451.          CLOSE( Message_File );
  452.             (*$I+*)
  453.  
  454.          IF ( NOT Open_For_Append( Message_File , Home_Dir + 'PIBTERM.MSG' , Ierr ) ) THEN
  455.             BEGIN
  456.                Host_Send_String( CR_LF_Host );
  457.                Host_Send_String_With_CR('Sorry, no more room for messages');
  458.                Quit := TRUE;
  459.             END;
  460.  
  461.       END;
  462.  
  463.    Host_Send_String( CR_LF_Host );
  464.    Host_Prompt_And_Read_String('Enter recipient''s name or ALL: ',
  465.                                   Recipient_Name, TRUE );
  466.  
  467.    Recipient_Name := UpperCase( TRIM( Recipient_Name ) );
  468.  
  469.    IF Recipient_Name = '' THEN
  470.       Recipient_Name := 'ALL';
  471.  
  472.    Host_Send_String( CR_LF_Host );
  473.    Host_Prompt_And_Read_String('Enter title for message: ',
  474.                                Message_Subject, TRUE );
  475.  
  476.    IF ( NOT Quit ) THEN
  477.       Get_A_Message( Message_File );
  478.  
  479.       (*$I-*)
  480.    CLOSE ( Message_File );
  481.       (*$I+*)
  482.                                    (* Increment message count *)
  483.    NMessages := NMessages + 1;
  484.  
  485.    Write_Log('Enter message.', FALSE, FALSE );
  486.  
  487.    Host_Status(Cur_Host_Status);
  488.  
  489. END   (* Enter_Message *);
  490.  
  491. (*----------------------------------------------------------------------*)
  492. (*    Skip_To_Message  --- Skip to specified message in message base    *)
  493. (*----------------------------------------------------------------------*)
  494.  
  495. PROCEDURE Skip_To_Message( Msg_No : INTEGER );
  496.  
  497. (*----------------------------------------------------------------------*)
  498. (*                                                                      *)
  499. (*     Procedure:  Skip_To_Message                                      *)
  500. (*                                                                      *)
  501. (*     Purpose:    Skip to specified message in message base.           *)
  502. (*                                                                      *)
  503. (*     Calling Sequence:                                                *)
  504. (*                                                                      *)
  505. (*        Skip_To_Message( Msg_No : INTEGER );                          *)
  506. (*                                                                      *)
  507. (*           Msg_No --- Message to skip to.                             *)
  508. (*                                                                      *)
  509. (*     Remarks:                                                         *)
  510. (*                                                                      *)
  511. (*        The message file must be opened before this routine is        *)
  512. (*        called.                                                       *)
  513. (*                                                                      *)
  514. (*----------------------------------------------------------------------*)
  515.  
  516. VAR
  517.    Msg_Count : INTEGER;
  518.  
  519. BEGIN (* Skip_To_Message *)
  520.  
  521.    Msg_Count := 0;
  522.  
  523.    REPEAT
  524.  
  525.       READLN( Message_File , Message_Line );
  526.  
  527.       IF COPY( Message_Line, 1, 6 ) = '== End' THEN
  528.          Msg_Count := Msg_Count + 1;
  529.  
  530.    UNTIL ( Msg_Count = ( Msg_No - 1 ) );
  531.  
  532. END   (* Skip_To_Message *);
  533.  
  534. (*----------------------------------------------------------------------*)
  535. (*             Read_Messages  --- Read messages from message base       *)
  536. (*----------------------------------------------------------------------*)
  537.  
  538. PROCEDURE Read_Messages;
  539.  
  540. (*----------------------------------------------------------------------*)
  541. (*                                                                      *)
  542. (*     Procedure:  Read_Messages                                        *)
  543. (*                                                                      *)
  544. (*     Purpose:    Reads messages currently in message base.            *)
  545. (*                                                                      *)
  546. (*     Calling Sequence:                                                *)
  547. (*                                                                      *)
  548. (*        Read_Messages;                                                *)
  549. (*                                                                      *)
  550. (*----------------------------------------------------------------------*)
  551.  
  552. VAR
  553.    Message_No   : INTEGER;
  554.    CMessage_No  : STRING[5];
  555.    I            : INTEGER;
  556.    Line_Count   : INTEGER;
  557.    Read_Done    : BOOLEAN;
  558.    Start_Msg    : INTEGER;
  559.    Start_M_Str  : AnyStr;
  560.    OK_Number    : BOOLEAN;
  561.  
  562. LABEL
  563.    Reading_Done;
  564.  
  565. BEGIN (* Read_Messages *)
  566.  
  567.    Host_Status('Read message');
  568.                                    (* Open message file *)
  569.  
  570.    ASSIGN( Message_File , Home_Dir + 'PIBTERM.MSG' );
  571.       (*$I-*)
  572.    RESET( Message_File );
  573.       (*$I+*)
  574.                                    (* Not there -- no messages *)
  575.    IF Int24Result <> 0 THEN
  576.       BEGIN
  577.          Host_Send_String( CR_LF_Host );
  578.          Host_Send_String_With_CR('No messages in message file.');
  579.          EXIT;
  580.       END;
  581.                                    (* Find where to start *)
  582.    REPEAT
  583.  
  584.       OK_Number := TRUE;
  585.  
  586.       Host_Send_String_With_CR(' ');
  587.  
  588.       STR( NMessages , Start_M_Str );
  589.  
  590.       IF ( NMessages = 1 ) THEN
  591.          Start_M_Str := 'There is 1 message in message base.'
  592.       ELSE
  593.          Start_M_Str := 'There are ' + Start_M_Str + ' messages in message base.';
  594.  
  595.       Host_Send_String_With_CR(Start_M_Str);
  596.  
  597.       Host_Prompt_And_Read_String('Enter message to start at or <CR> for all: ',
  598.                                    Start_M_Str, TRUE );
  599.       Start_Msg := 0;
  600.       FOR I := 1 TO LENGTH( Start_M_Str ) DO
  601.          IF ( Start_M_Str[I] IN ['0'..'9'] ) THEN
  602.             Start_Msg := Start_Msg * 10 + ORD( Start_M_Str[I] ) - ORD('0')
  603.          ELSE
  604.             OK_Number := FALSE;
  605.  
  606.       IF Start_Msg = 0 THEN Start_Msg := 1;
  607.       IF Start_Msg > NMessages THEN Start_Msg := NMessages;
  608.  
  609.    UNTIL ( NOT Host_Carrier_Detect ) OR ( OK_Number );
  610.  
  611.    IF ( NOT Host_Carrier_Detect ) THEN GOTO Reading_Done;
  612.  
  613.                                    (* Skip to desired message *)
  614.    Skip_To_Message( Start_Msg );
  615.  
  616.                                    (* Messages always start at one *)
  617.    Message_No := Start_Msg - 1;
  618.    Read_Done  := FALSE;
  619.    Line_Count := 0;
  620.                                    (* Loop over messages *)
  621.    REPEAT
  622.                                    (* Increment message number *)
  623.  
  624.       Message_No := Message_No + 1;
  625.  
  626.       STR( Message_No : 5 , CMessage_No );
  627.  
  628.       Host_Send_String( CR_LF_Host );
  629.       List_Prompt( Line_Count , Read_Done );
  630.       IF Read_Done THEN GOTO Reading_Done;
  631.  
  632.       Host_Send_String_With_CR('Message #' + CMessage_No);
  633.       List_Prompt( Line_Count , Read_Done );
  634.       IF Read_Done THEN GOTO Reading_Done;
  635.  
  636.                                    (* Display message # and header info *)
  637.       FOR I := 1 TO 5 DO
  638.          BEGIN
  639.             READLN( Message_File , Message_Line );
  640.             Message_Line := COPY( Message_Line, 4,
  641.                                   LENGTH( Message_Line ) - 3 );
  642.             Host_Send_String_With_CR( Message_Line );
  643.             List_Prompt( Line_Count , Read_Done );
  644.             IF Read_Done THEN GOTO Reading_Done;
  645.          END;
  646.  
  647.       Host_Send_String_With_CR(' ');
  648.       List_Prompt( Line_Count , Read_Done );
  649.       IF Read_Done THEN GOTO Reading_Done;
  650.  
  651.                                    (* Display body of message *)
  652.       REPEAT
  653.  
  654.          READLN( Message_File , Message_Line );
  655.  
  656.          IF ( COPY( Message_Line, 1, 6 ) <> '== End' ) THEN
  657.             BEGIN
  658.                Host_Send_String_With_CR( COPY( Message_Line, 2,
  659.                                                 LENGTH( Message_Line ) - 1 ) );
  660.                List_Prompt( Line_Count , Read_Done );
  661.             END;
  662.  
  663.       UNTIL ( COPY( Message_Line, 1, 6 ) = '== End' ) OR ( Read_Done );
  664.  
  665.    UNTIL ( Message_No >= NMessages ) OR Read_Done;
  666.  
  667. Reading_Done:
  668.  
  669.    Host_Send_String_With_CR(' ');
  670.    Host_Prompt_And_Read_String('Finished reading messages, hit <CR> to continue: ',
  671.                                Start_M_Str, TRUE );
  672.    Host_Send_String_With_CR(' ');
  673.  
  674.       (*$I-*)
  675.    CLOSE( Message_File );
  676.       (*$I+*)
  677.  
  678.    Write_Log('Read messages.', FALSE, FALSE );
  679.  
  680.    Host_Status(Cur_Host_Status);
  681.  
  682. END   (* Read_Messages *);
  683.  
  684. (*----------------------------------------------------------------------*)
  685. (*             Scan_Messages  --- Scan messages from message base       *)
  686. (*----------------------------------------------------------------------*)
  687.  
  688. PROCEDURE Scan_Messages( Personal_Only : BOOLEAN );
  689.  
  690. (*----------------------------------------------------------------------*)
  691. (*                                                                      *)
  692. (*     Procedure:  Scan_Messages                                        *)
  693. (*                                                                      *)
  694. (*     Purpose:    Scans message headers currently in message base.     *)
  695. (*                                                                      *)
  696. (*     Calling Sequence:                                                *)
  697. (*                                                                      *)
  698. (*        Scan_Messages( Personal_Only : BOOLEAN );                     *)
  699. (*                                                                      *)
  700. (*           Personal_Only --- Return messages addressed to current     *)
  701. (*                             user only.                               *)
  702. (*                                                                      *)
  703. (*----------------------------------------------------------------------*)
  704.  
  705. VAR
  706.    Message_Title: AnyStr;
  707.    Message_No   : INTEGER;
  708.    CMessage_No  : STRING[5];
  709.    I            : INTEGER;
  710.    Line_Count   : INTEGER;
  711.    Scan_Done    : BOOLEAN;
  712.    OK_Number    : BOOLEAN;
  713.    Start_Msg    : INTEGER;
  714.    Start_M_Str  : AnyStr;
  715.    Message_L1   : AnyStr;
  716.    Message_L2   : AnyStr;
  717.    Msg_Count    : INTEGER;
  718.  
  719. LABEL
  720.    Scanning_Done;
  721.  
  722. BEGIN (* Scan_Messages *)
  723.  
  724.    Host_Status('Scan messages');
  725.                                    (* Open message file *)
  726.  
  727.    ASSIGN( Message_File , Home_Dir + 'PIBTERM.MSG' );
  728.       (*$I-*)
  729.    RESET( Message_File );
  730.       (*$I+*)
  731.                                    (* Not there -- no messages *)
  732.    IF Int24Result <> 0 THEN
  733.       BEGIN
  734.          Host_Send_String( CR_LF_Host );
  735.          Host_Send_String_With_CR('No messages in message file.');
  736.          GOTO Scanning_Done;
  737.       END;
  738.                                    (* Find where to start -- if only *)
  739.                                    (* personal messages, always scan *)
  740.                                    (* entire message base.           *)
  741.    Start_Msg := 1;
  742.  
  743.    IF ( NOT Personal_Only ) THEN
  744.       REPEAT
  745.                                    (* Request starting message number *)
  746.          OK_Number := TRUE;
  747.  
  748.          Host_Send_String_With_CR(' ');
  749.  
  750.          STR( NMessages , Start_M_Str );
  751.          IF ( NMessages = 1 ) THEN
  752.             Start_M_Str := 'There is 1 message in message base.'
  753.          ELSE
  754.             Start_M_Str := 'There are ' + Start_M_Str + ' messages in message base.';
  755.          Host_Send_String_With_CR(Start_M_Str);
  756.  
  757.          Host_Prompt_And_Read_String('Enter message to start at or <CR> for all: ',
  758.                                       Start_M_Str, TRUE );
  759.  
  760.                                    (* Convert response to message number *)
  761.          Start_Msg := 0;
  762.  
  763.          FOR I := 1 TO LENGTH( Start_M_Str ) DO
  764.             IF ( Start_M_Str[I] IN ['0'..'9'] ) THEN
  765.                Start_Msg := Start_Msg * 10 + ORD( Start_M_Str[I] ) - ORD('0')
  766.             ELSE
  767.                OK_Number := FALSE;
  768.                                    (* Ensure message is in range *)
  769.  
  770.          IF Start_Msg = 0 THEN Start_Msg := 1;
  771.          IF Start_Msg > NMessages THEN Start_Msg := NMessages;
  772.  
  773.       UNTIL ( NOT Host_Carrier_Detect ) OR ( OK_Number );
  774.  
  775.    IF ( NOT Host_Carrier_Detect ) THEN GOTO Scanning_Done;
  776.  
  777.                                    (* Skip to desired message *)
  778.    Skip_To_Message( Start_Msg );
  779.                                    (* Messages always start at one *)
  780.    Message_No := Start_Msg - 1;
  781.    Line_Count := 0;
  782.    Scan_Done  := FALSE;
  783.    Msg_Count  := 0;
  784.                                    (* Loop over messages *)
  785.    REPEAT
  786.                                    (* Increment message number *)
  787.       Message_No := Message_No + 1;
  788.  
  789.                                    (* Read 1st two lines of message *)
  790.  
  791.       READLN( Message_File , Message_L1 );
  792.       READLN( Message_File , Message_L2 );
  793.  
  794.                                    (* Check if recipient is current user *)
  795.  
  796.       IF ( COPY( Message_L2, 13, LENGTH( Message_L2 ) - 12 ) =
  797.            UpperCase( Cur_User_Name ) ) OR ( NOT Personal_Only ) THEN
  798.  
  799.          BEGIN (* Display this message *)
  800.  
  801.                                    (* Increment personal messages count *)
  802.  
  803.             Msg_Count := Msg_Count + 1;
  804.  
  805.             STR( Message_No : 5 , CMessage_No );
  806.  
  807.             Host_Send_String( CR_LF_Host );
  808.             List_Prompt( Line_Count , Scan_Done );
  809.             IF Scan_Done THEN GOTO Scanning_Done;
  810.  
  811.                                    (* Display message number *)
  812.  
  813.             Host_Send_String_With_CR('Message #' + CMessage_No );
  814.             List_Prompt( Line_Count , Scan_Done );
  815.             IF Scan_Done THEN GOTO Scanning_Done;
  816.  
  817.                                    (* Display 1st 2 header lines *)
  818.  
  819.             Host_Send_String_With_CR( COPY( Message_L1, 4,
  820.                                        LENGTH( Message_L1 ) - 3 ) );
  821.             List_Prompt( Line_Count , Scan_Done );
  822.             IF Scan_Done THEN GOTO Scanning_Done;
  823.  
  824.             Host_Send_String_With_CR( COPY( Message_L2, 4,
  825.                                        LENGTH( Message_L2 ) - 3 ) );
  826.             List_Prompt( Line_Count , Scan_Done );
  827.             IF Scan_Done THEN GOTO Scanning_Done;
  828.  
  829.                                    (* Display remaining header info *)
  830.             FOR I := 3 TO 5 DO
  831.                BEGIN
  832.                   READLN( Message_File , Message_Line );
  833.                   Message_Line := COPY( Message_Line, 4,
  834.                                         LENGTH( Message_Line ) - 3 );
  835.                   Host_Send_String_With_CR( Message_Line );
  836.                   List_Prompt( Line_Count , Scan_Done );
  837.                   IF Scan_Done THEN GOTO Scanning_Done;
  838.                END;
  839.  
  840.             Host_Send_String_With_CR(' ');
  841.             List_Prompt( Line_Count , Scan_Done );
  842.  
  843.          END (* Display this message *);
  844.  
  845.                                    (* Scan for end of message *)
  846.       IF ( NOT Scan_Done ) THEN
  847.          REPEAT
  848.             READLN( Message_File , Message_Line );
  849.          UNTIL ( COPY( Message_Line, 1, 6 ) = '== End' );
  850.  
  851.    UNTIL ( Message_No >= NMessages ) OR ( Scan_Done );
  852.  
  853. Scanning_Done:
  854.  
  855.       (*$I-*)
  856.    CLOSE( Message_File );
  857.       (*$I+*)
  858.                                    (* Notify user if no personal messages *)
  859.    IF Personal_Only THEN
  860.       IF Msg_Count = 0 THEN
  861.          BEGIN
  862.             Host_Send_String_With_CR(' ');
  863.             Host_Send_String_With_CR('You have no personal messages waiting.');
  864.          END;
  865.  
  866.    Host_Send_String_With_CR(' ');
  867.    Host_Prompt_And_Read_String('Finished scanning messages, hit <CR> to continue: ',
  868.                                Start_M_Str, TRUE );
  869.    Host_Send_String_With_CR(' ');
  870.  
  871.    Write_Log('Scan messages.', FALSE, FALSE );
  872.  
  873.    Host_Status(Cur_Host_Status);
  874.  
  875. END   (* Scan_Messages *);
  876.  
  877. (*----------------------------------------------------------------------*)
  878. (*                   Enter_Comment  --- Enter a comment                 *)
  879. (*----------------------------------------------------------------------*)
  880.  
  881. PROCEDURE Enter_Comment;
  882.  
  883. (*----------------------------------------------------------------------*)
  884. (*                                                                      *)
  885. (*     Procedure:  Enter_Comment                                        *)
  886. (*                                                                      *)
  887. (*     Purpose:    Enters comment into comment file.                    *)
  888. (*                                                                      *)
  889. (*     Calling Sequence:                                                *)
  890. (*                                                                      *)
  891. (*        Enter_Comment;                                                *)
  892. (*                                                                      *)
  893. (*     Calls:                                                           *)
  894. (*                                                                      *)
  895. (*        Open_For_Append                                               *)
  896. (*        Get_A_Message                                                 *)
  897. (*                                                                      *)
  898. (*     Remarks:                                                         *)
  899. (*                                                                      *)
  900. (*        The comments file is PIBTERM.CMT.                             *)
  901. (*                                                                      *)
  902. (*----------------------------------------------------------------------*)
  903.  
  904. VAR
  905.    Quit          : BOOLEAN;
  906.    Ierr          : INTEGER;
  907.    Comments_File : Text_File;
  908.  
  909. BEGIN (* Enter_Comment *)
  910.  
  911.    Host_Status('Enter comment');
  912.  
  913.    Quit := FALSE;
  914.                                    (* Open comments file *)
  915.  
  916.    ASSIGN( Comments_File, Home_Dir + 'PIBTERM.CMT' );
  917.       (*$I-*)
  918.    RESET ( Comments_File );
  919.       (*$I+*)
  920.                                    (* If it exists, open for append.       *)
  921.                                    (* If it doesn't exist, open for write. *)
  922.    IF Int24Result <> 0 THEN
  923.       BEGIN
  924.          WRITELN('Creating comments file PIBTERM.CMT');
  925.             (*$I-*)
  926.          REWRITE( Comments_File );
  927.             (*$I+*)
  928.          IF Int24Result <> 0 THEN
  929.             BEGIN
  930.                Host_Send_String( CR_LF_Host );
  931.                Host_Send_String_With_CR('Sorry, can''t accept comments now.');
  932.                Quit := TRUE;
  933.             END;
  934.       END
  935.    ELSE
  936.       BEGIN
  937.             (*$I-*)
  938.          CLOSE( Comments_File );
  939.             (*$I+*)
  940.  
  941.          IF ( NOT Open_For_Append( Comments_File ,
  942.                                    Home_Dir + 'PIBTERM.CMT', Ierr ) ) THEN
  943.             BEGIN
  944.                Host_Send_String( CR_LF_Host );
  945.                Host_Send_String_With_CR('Sorry, can''t accept comments now.');
  946.                Quit := TRUE;
  947.             END;
  948.  
  949.       END;
  950.  
  951.    Recipient_Name  := 'SYSOP';
  952.    Message_Subject := ' ';
  953.  
  954.    IF ( NOT Quit ) THEN
  955.       Get_A_Message( Comments_File );
  956.  
  957.       (*$I-*)
  958.    CLOSE ( Comments_File );
  959.       (*$I+*)
  960.  
  961.    Write_Log('Enter comment to SYSOP.', FALSE, FALSE );
  962.  
  963.    Host_Status(Cur_Host_Status);
  964.  
  965. END   (* Enter_Comment *);
  966.  
  967. (*----------------------------------------------------------------------*)
  968. (*   Display_Welcome_Message --- Display welcome message after login    *)
  969. (*----------------------------------------------------------------------*)
  970.  
  971. PROCEDURE Display_Welcome_Message;
  972.  
  973. (*----------------------------------------------------------------------*)
  974. (*                                                                      *)
  975. (*     Procedure:  Display_Welcome_Message                              *)
  976. (*                                                                      *)
  977. (*     Purpose:    Displays welcome message after successful login      *)
  978. (*                                                                      *)
  979. (*     Calling Sequence:                                                *)
  980. (*                                                                      *)
  981. (*        Display_Welcome_Message;                                      *)
  982. (*                                                                      *)
  983. (*     Calls:                                                           *)
  984. (*                                                                      *)
  985. (*        Open_For_Append                                               *)
  986. (*        Get_A_Message                                                 *)
  987. (*                                                                      *)
  988. (*     Remarks:                                                         *)
  989. (*                                                                      *)
  990. (*        The welcome text is in file PIBTERM.WEL.                      *)
  991. (*                                                                      *)
  992. (*----------------------------------------------------------------------*)
  993.  
  994. VAR
  995.    Welcome_File : Text_File;
  996.    Welcome_Line : AnyStr;
  997.    Line_Count   : INTEGER;
  998.    List_Done    : BOOLEAN;
  999.  
  1000. BEGIN (* Display_Welcome_Message *)
  1001.  
  1002.    ASSIGN( Welcome_File , Home_Dir + 'PIBTERM.WEL' );
  1003.       (*$I-*)
  1004.    RESET( Welcome_File );
  1005.       (*$I+*)
  1006.  
  1007.    IF ( INT24Result = 0 ) THEN
  1008.       BEGIN
  1009.  
  1010.          Line_Count  := 0;
  1011.          List_Done   := FALSE;
  1012.  
  1013.          REPEAT
  1014.             READLN( Welcome_File , Welcome_Line );
  1015.             Host_Send_String_With_Cr( Welcome_Line );
  1016.             List_Prompt( Line_Count , List_Done );
  1017.          UNTIL ( EOF( Welcome_File ) OR List_Done );
  1018.  
  1019.             (*$I-*)
  1020.          CLOSE( Welcome_File );
  1021.             (*$I+*)
  1022.  
  1023.          End_Prompt('End of welcome, hit <CR> to continue: ');
  1024.  
  1025.       END;
  1026.  
  1027. END   (* Display_Welcome_Message *);
  1028.  
  1029. (*----------------------------------------------------------------------*)
  1030.  
  1031. BEGIN (* Process_Host_Commands *)
  1032.  
  1033.                                    (* Scan for personal mail on *)
  1034.                                    (* first entry here.         *)
  1035.    IF Host_Section = 'I' THEN
  1036.       BEGIN
  1037.  
  1038.          Display_Welcome_Message;
  1039.          Host_Send_String_With_CR(' ');
  1040.  
  1041.          Host_Send_String_With_CR(' ');
  1042.          Host_Send_String_With_CR('Scanning for personal messages ... ');
  1043.  
  1044.          Scan_Messages( TRUE );
  1045.  
  1046.          Host_Section := 'M';
  1047.  
  1048.       END;
  1049.  
  1050.    Cur_Host_Status := 'Message section';
  1051.    Host_Status( Cur_Host_Status );
  1052.  
  1053.                                    (* Prompt for commands *)
  1054.    Display_Host_Commands;
  1055.                                    (* Assume input from remote *)
  1056.  
  1057. ReadChar:
  1058.  
  1059.    Kbd_Input := FALSE;
  1060.                                    (* Wait for command to be entered *)
  1061.    REPEAT
  1062.       Done     := Done OR ( NOT Host_Carrier_Detect );
  1063.       Found_Ch := Async_Receive( Ch ) OR KeyPressed;
  1064.       IF ( NOT Found_Ch ) THEN
  1065.          GiveAwayTime( 2 );
  1066.    UNTIL Done OR Found_Ch;
  1067.  
  1068.                                    (* Process input from keyboard *)
  1069.    IF KeyPressed THEN
  1070.       BEGIN
  1071.          READ( KBD , Ch );
  1072.          Kbd_Input := TRUE;
  1073.          IF ( ORD( Ch ) = ESC ) AND KeyPressed THEN
  1074.             BEGIN
  1075.                READ( Kbd, Ch );
  1076.                CASE ORD( Ch ) OF
  1077.                   F1 : Ch := 'G';
  1078.                   F2 : Ch := 'Q';
  1079.                   F3 : BEGIN
  1080.                           DosJump('');
  1081.                           Ch := ' ';
  1082.                        END;
  1083.                   F5 : BEGIN
  1084.                           WRITELN;
  1085.                           WRITELN('Current caller is ',Cur_User_Name);
  1086.                           Ch := ' ';
  1087.                        END;
  1088.                END (* CASE *);
  1089.             END;
  1090.       END;
  1091.  
  1092.    IF ( Ch = ' ' ) THEN GOTO ReadChar;
  1093.  
  1094.    IF ( Not DONE ) THEN
  1095.                                    (* Echo command *)
  1096.  
  1097.       Host_Send_String( Ch + CR_LF_Host );
  1098.       WRITELN;
  1099.       IF Printer_On THEN
  1100.          WRITELN( Lst, Ch );
  1101.       IF Capture_On THEN
  1102.          WRITELN( Capture_File, Ch );
  1103.  
  1104.                                    (* Process command request *)
  1105.       CASE UpCase( Ch ) OF
  1106.  
  1107.          'E':  Enter_Message;
  1108.          'R':  Read_Messages;
  1109.          'Q':  BEGIN
  1110.                   IF Kbd_Input THEN
  1111.                      BEGIN
  1112.                         Host_Send_String_With_CR('System operator shutting ' +
  1113.                                                   'down system.');
  1114.                         Host_Send_String_With_CR('Thanks for calling.');
  1115.                         Done := TRUE;
  1116.                      END
  1117.                   ELSE
  1118.                      BEGIN
  1119.                         Host_Send_String_With_CR('Quit and logoff');
  1120.                         Done := TRUE;
  1121.                      END;
  1122.                END;
  1123.          'F':  Host_Section := 'F';
  1124.          'G':  BEGIN
  1125.                   IF Kbd_Input THEN
  1126.                      BEGIN
  1127.                         Host_Send_String_With_CR(' ... System operator wishes' +
  1128.                                                   ' to chat, please wait ...');
  1129.                         Host_Send_String_With_CR(' ');
  1130.                         Host_Section   := 'G';
  1131.                         Last_Host_Sect := 'M';
  1132.                      END
  1133.                   ELSE
  1134.                      BEGIN
  1135.                         Page_Sysop( Sysop_Found );
  1136.                         IF Sysop_Found THEN
  1137.                            BEGIN
  1138.                               Host_Section   := 'G';
  1139.                               Last_Host_Sect := 'M';
  1140.                            END;
  1141.                      END;
  1142.                END;
  1143.          'C':  Enter_Comment;
  1144.          'P':  Scan_Messages( TRUE );
  1145.          'X':  Expert_On := NOT Expert_On;
  1146.          'S':  Scan_Messages( FALSE );
  1147.          'J':  IF ( Privilege = 'S' ) THEN
  1148.                   BEGIN
  1149.                      Host_Section   := 'D';
  1150.                      Last_Host_Sect := 'M';
  1151.                   END
  1152.                ELSE
  1153.                   Host_Send_String( ^G );
  1154.  
  1155.          'W':  Display_Welcome_Message;
  1156.  
  1157.          ELSE  Host_Send_String( ^G );
  1158.  
  1159.       END (* CASE *)
  1160.  
  1161. END   (* Process_Host_Commands *);
  1162.  
  1163. (*----------------------------------------------------------------------*)
  1164. (*           Get_UserInfo --- Read in user name and password            *)
  1165. (*----------------------------------------------------------------------*)
  1166.  
  1167. PROCEDURE Get_UserInfo( VAR Found: BOOLEAN );
  1168.  
  1169. (*----------------------------------------------------------------------*)
  1170. (*                                                                      *)
  1171. (*     Procedure:  Get_UserInfo                                         *)
  1172. (*                                                                      *)
  1173. (*     Purpose:    Gets user name and password from remote user.        *)
  1174. (*                                                                      *)
  1175. (*     Calling Sequence:                                                *)
  1176. (*                                                                      *)
  1177. (*        Get_UserInfo( VAR Found: BOOLEAN );                           *)
  1178. (*                                                                      *)
  1179. (*           Done --- set TRUE if user name found and carrier not       *)
  1180. (*                    dropped.                                          *)
  1181. (*                                                                      *)
  1182. (*----------------------------------------------------------------------*)
  1183.  
  1184. VAR
  1185.    MyPass   : AnyStr;
  1186.    CallLine : AnyStr;
  1187.    Ierr     : INTEGER;
  1188.  
  1189. BEGIN (* Get_UserInfo *)
  1190.  
  1191.    Host_Status('Get user info');
  1192.  
  1193.                                    (* Prompt for first name *)
  1194.  
  1195.    Host_Send_String_With_CR(' ');
  1196.    Host_Prompt_And_Read_String('Enter first name: ', Fname, TRUE );
  1197.    Fname := TRIM( UpperCase( Fname ) );
  1198.  
  1199.                                    (* Prompt for second name *)
  1200.  
  1201.    Host_Send_String_With_CR(' ');
  1202.    Host_Prompt_And_Read_String('Enter last name:  ', Lname, TRUE );
  1203.    Lname := TRIM( UpperCase( Lname ) );
  1204.  
  1205.                                    (* See if valid user name *)
  1206.    Cur_User      := 0;
  1207.    Found         := FALSE;
  1208.    Privilege     := 'N';
  1209.    Cur_User_Name := '';
  1210.  
  1211.    IF ( LENGTH( Fname ) > 0 ) AND ( LENGTH( Lname ) > 0 ) THEN
  1212.       REPEAT
  1213.          Cur_User := Cur_User + 1;
  1214.          WITH User_List^[Cur_User] DO
  1215.             Found := ( Fname = First_Name ) AND ( Lname = Last_Name );
  1216.       UNTIL ( Found OR ( Cur_User >= NUsers ) );
  1217.  
  1218.                                    (* Remember name for message scans *)
  1219.  
  1220.    Cur_User_Name := Fname + ' ' + Lname;
  1221.  
  1222.                                    (* Error if name not in user file *)
  1223.    IF ( NOT Found ) THEN
  1224.       BEGIN
  1225.          Host_Send_String_With_CR(' ');
  1226.          Host_Send_String_With_CR('Not a valid user name.');
  1227.       END;
  1228.                                    (* Prompt for password *)
  1229.  
  1230.    IF ( Found AND Host_Carrier_Detect ) THEN
  1231.       BEGIN
  1232.  
  1233.          Host_Send_String_With_CR(' ');
  1234.          Host_Prompt_And_Read_String('Enter Password:   ', MyPass, FALSE );
  1235.          Host_Send_String_With_CR(' ');
  1236.  
  1237.                                    (* Check if password valid *)
  1238.  
  1239.          IF MyPass = User_List^[Cur_User].PassWord THEN
  1240.             BEGIN
  1241.  
  1242.                Host_Send_String_With_CR('Password OK');
  1243.  
  1244.                Found := TRUE;
  1245.  
  1246.                Write_Log( Fname + ' ' + Lname + ' logged in.', FALSE, FALSE );
  1247.  
  1248.                                    (* Pick up privilege of user *)
  1249.  
  1250.                Privilege := User_List^[Cur_User].Privilege;
  1251.  
  1252.             END
  1253.          ELSE
  1254.             BEGIN
  1255.  
  1256.                Host_Send_String_With_CR('Password wrong');
  1257.  
  1258.                Found := FALSE;
  1259.  
  1260.                Write_Log( Fname + ' ' + Lname +
  1261.                           ' logon try with bad password = ' + MyPass,
  1262.                           FALSE, FALSE );
  1263.  
  1264.             END;
  1265.  
  1266.    END;
  1267.                                    (* Update status line *)
  1268.    IF Found THEN
  1269.       BEGIN
  1270.          Cur_Host_Status := Cur_User_Name;
  1271.          Host_Status( Cur_Host_Status );
  1272.       END;
  1273.  
  1274. END   (* Get_UserInfo *);
  1275.